#include "planner/rules/implementation_rules.h"

#include <memory>
#include <utility>
#include <vector>

#include "planner/logical_operators.h"
#include "planner/optimizer_defs.h"
#include "planner/physical_operators.h"

namespace optimizer {

///////////////////////////////////////////////////////////////////////////////
/// LogicalGetToPhysicalSeqScan
///////////////////////////////////////////////////////////////////////////////
LogicalGetToPhysicalSeqScan::LogicalGetToPhysicalSeqScan() {
  type_ = RuleType::GET_TO_SEQ_SCAN;
  match_pattern_ = new Pattern(OperatorType::LogicalGet);
}

bool LogicalGetToPhysicalSeqScan::Check(std::shared_ptr<Operator> plan, OptimizationContext *context) const {
  (void)context;
  return true;
}

void LogicalGetToPhysicalSeqScan::Transform(std::shared_ptr<Operator> input,
                                            std::vector<std::shared_ptr<Operator>> &transformed,
                                            UNUSED_ATTRIBUTE OptimizationContext *context) const {
  CASCADES_ASSERT(input->GetChildren().empty(), "Get should have no children");
  const auto get = input->CastTo<LogicalGet>();

  auto result_plan = std::make_shared<PhysicalSeqScan>(get.GetRangeTblEntry());
  result_plan->SetFilter(get.GetFilter());
  result_plan->SetProject(get.GetProject());
  transformed.emplace_back(std::move(result_plan));
}

}  // namespace optimizer
